home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-07-03 | 3.8 KB | 133 lines | [TEXT/R*ch] |
- (* StringCvt -- new basis 1995-04-06 *)
-
- local
- prim_val sub_ : string -> int -> char = 2 "get_nth_char";
- prim_val fromchr_ : char -> string = 1 "sml_makestring_of_char";
- prim_val fromstr_ : string -> string = 1 "sml_makestring_of_string";
-
- fun decval c = Char.ord c - 48;
- fun getndig getc 0 res src = SOME (res, src)
- | getndig getc n res src =
- case getc src of
- NONE => NONE
- | SOME (c, rest) =>
- if Char.isDigit c then
- getndig getc (n-1) (10 * res + decval c) rest
- else NONE;
- in
-
- datatype radix = BIN | OCT | DEC | HEX;
- datatype realfmt =
- SCI of int option (* scientific, arg = # dec. digits, dflt=6 *)
- | FIX of int option (* fixed-point, arg = # dec. digits, dflt=6 *)
- | GEN of int option (* auto choice of the above, *)
- (* arg = # significant digits, dflt=12 *)
-
- type 'stream accessor = {getc : 'stream -> (char * 'stream) option}
- type ('stream, 'result) converter =
- 'stream accessor -> 'stream -> ('result * 'stream) option
-
- fun scanString scan s =
- let val len = size s
- fun getc i = if i >= len then NONE
- else SOME (sub_ s i, i+1)
- in case scan {getc=getc} 0 of
- NONE => NONE
- | SOME (res, _) => SOME res
- end
-
- fun skipWS {getc} source =
- case getc source of
- NONE => source
- | SOME (c, rest) =>
- if c = #" " orelse c = #"\t" orelse c = #"\n" then
- skipWS {getc=getc} rest
- else source;
-
- fun escape getc source =
- let fun skipform src =
- case getc (skipWS {getc=getc} src) of
- NONE => NONE
- | SOME(#"\\", rest) => escape getc rest
- in
- case getc source of
- NONE => NONE
- | SOME(#"n", rest) => SOME(#"\n", rest)
- | SOME(#"t", rest) => SOME(#"\t", rest)
- | SOME(#"\"", rest) => SOME(#"\"", rest)
- | SOME(#"\\", rest) => SOME(#"\\", rest)
- | SOME(#" ", rest) => skipform rest
- | SOME(#"\n", rest) => skipform rest
- | SOME(#"\t", rest) => skipform rest
- | SOME(#"^", rest) =>
- (case getc rest of
- NONE => NONE
- | SOME(c, rest) =>
- if #"@" <= c andalso c <= #"_" then
- SOME(Char.chr(Char.ord c - 64), rest)
- else
- NONE)
- | _ =>
- (case getndig getc 3 0 source of
- NONE => NONE
- | SOME(code, rest) =>
- if code > Char.maxOrd then NONE
- else SOME(Char.chr code, rest))
- end
-
-
- fun fromChar c =
- let val s = fromchr_ c
- in String.substring(s, 2, String.size s - 3) end
- fun fromString s =
- let val ss = fromstr_ s
- in String.substring(ss, 1, String.size ss - 2) end
-
- fun scantoChar {getc} source =
- case getc source of
- NONE => NONE
- | SOME(#"\\", rest) => escape getc rest
- | SOME(#"\"", rest) => NONE
- | res => res;
-
- fun scantoString {getc} source =
- let fun h src res =
- case scantoChar {getc=getc} src of
- NONE => SOME(String.implode(List.rev res), src)
- | SOME(c, rest) => h rest (c :: res)
- in h source [] end;
-
- fun toChar s = scanString scantoChar s
- fun toString s = scanString scantoString s
-
- local
- prim_val mkstring_ : int -> string = 1 "create_string";
- prim_val fill_ : string -> int -> int -> char -> unit
- = 4 "fill_string";
- prim_val blit_ : string -> int -> string -> int -> int -> unit
- = 5 "blit_string";
- in
- fun padLeft c n s =
- let val ssize = size s
- in if n <= ssize then s
- else let val res = mkstring_ n
- in
- fill_ res 0 (n - ssize) c;
- blit_ s 0 res (n - ssize) ssize;
- res
- end
- end;
-
- fun padRight c n s =
- let val ssize = size s
- in if n <= ssize then s
- else let val res = mkstring_ n
- in
- blit_ s 0 res 0 ssize;
- fill_ res ssize (n - ssize) c;
- res
- end
- end;
- end
- end
-